﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using dIRca.WP7.ViewModels;
using Funq;
using WP7Contrib.Common;
using WP7Contrib.Logging;
using WP7Contrib.Services.Navigation;
using WP7Contrib.Services.Storage;
using dIRca.Data.Services;

namespace dIRca.WP7
{
    /// <summary>
    /// The boot strapper.
    /// </summary>
    public class BootStrapper : IDisposable
    {
        #region Constants and Fields

        /// <summary>
        /// The disposed.
        /// </summary>
        private bool disposed;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="BootStrapper"/> class.
        /// </summary>
        public BootStrapper()
        {
            this.Container = new Container();

            this.ConfigureContainer();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets Container.
        /// </summary>
        public Container Container { get; private set; }

        #endregion

        #region Implemented Interfaces

        #region IDisposable

        /// <summary>
        /// The dispose.
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (this.disposed)
                return;

            if (disposing)
            {
                this.Container.Dispose();
                this.Container = null;
            }
            this.disposed = true;
        }

        #endregion

        #endregion

        #region Methods

        /// <summary>
        /// The configure container.
        /// </summary>
        private void ConfigureContainer()
        {
            // ViewModelBaseWp7
            Container.Register<ILogManager>(c => new LoggingService("dIRca").Enable());

            Container.Register<ILog>(c => Container.Resolve<ILogManager>());

            var assemblies = new List<Assembly> { GetType().Assembly, typeof(BaseModel).Assembly };
            Container.Register<IStorageService>(c => new StorageService(assemblies, c.Resolve<ILog>()));

            Container.Register<INavigationService>(
                c => new ApplicationFrameNavigationService(((App)Application.Current).RootFrame));

            Container.Register<DatabaseService>(c => new DatabaseService());

            Container.Register<ILastConnectionService>(c => new LastConnectionService(
                                c.Resolve<DatabaseService>(), 
                                25));

            Container.Register<ISettingService>(c => new SettingService(
                c.Resolve<DatabaseService>()));

            // ViewModel
            Container.Register(c => new MainViewModel(
                c.Resolve<INavigationService>(),
                c.Resolve<IStorageService>(),
                c.Resolve<ILog>(),
                c.Resolve<ISettingService>(),
                c.Resolve<ILastConnectionService>()));
            Container.Register(c => new ConnectionsViewModel(
                c.Resolve<INavigationService>(),
                c.Resolve<ILog>(),
                c.Resolve<ILastConnectionService>()));
            Container.Register(c => new SettingsViewModel(
                c.Resolve<INavigationService>(),
                c.Resolve<IStorageService>(),
                c.Resolve<ILog>(),
                c.Resolve<ISettingService>()));
            Container.Register(c => new AboutViewModel(
                c.Resolve<INavigationService>(),
                c.Resolve<ILog>()));

            // Model dependencies
        }

        #endregion
    }
}
